package com.zndroid.base.ui.common;

import android.graphics.Color;
import android.os.Bundle;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.viewbinding.ViewBinding;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.binder.BaseItemBinder;
import com.zndroid.base.adapter.BaseAdapter;
import com.zndroid.base.callback.IOnItemChildLongClickListener;
import com.zndroid.base.callback.IOnItemClickListener;
import com.zndroid.base.callback.IOnItemLongClickListener;
import com.zndroid.base.callback.inner.mvp.IView;
import com.zndroid.base.exception.SupplyIsNullException;
import com.zndroid.base.ui.impl.BasePresenter;

import java.util.List;
import java.util.Observable;
import java.util.Observer;

/**
 * @author lazy
 * @date 3/23/21
 */
@SuppressWarnings("unused")
public abstract class CommonListActivity<VB extends ViewBinding, P extends BasePresenter<? extends IView>, A extends BaseAdapter<T>, T> extends CommonActivity<VB, P>
        implements Observer
{
    private @Nullable A adapter;
    private @Nullable RecyclerView recyclerView;
    private @Nullable SwipeRefreshLayout refreshLayout;

    /**
     * must supply Adapter instances of {@link BaseAdapter}
     * @return A a adapter
     * */
    protected abstract A onSupplyAdapter();
    /**
     * must supply ItemBinder instances of {@link BaseItemBinder} for showing.
     * @return B a BaseItemBinder
     * */
    protected abstract BaseItemBinder onSupplyItemBinder();
    /**
     * must supply RecyclerView instances of {@link RecyclerView}
     * @return RecyclerView
     * */
    protected abstract RecyclerView onSupplyRecyclerView();
    /**
     * supply {@link SwipeRefreshLayout} to refresh enable if you want.
     * @return SwipeRefreshLayout
     * */
    protected abstract SwipeRefreshLayout onSupplyRefreshLayout();

    /**
     * default {@link LinearLayoutManager}
     * @return RecyclerView.LayoutManager
     * */
    protected RecyclerView.LayoutManager onSupplyLayoutManager() {
        return new LinearLayoutManager(getApplicationContext());
    }

    /**
     * default {@link RecyclerView.ItemDecoration}
     * @return RecyclerView.ItemDecoration
     * */
    protected RecyclerView.ItemDecoration onSupplyItemDecoration() {
        return new DividerItemDecoration(getApplicationContext(), DividerItemDecoration.VERTICAL);
    }

    /**
     * switch enable refresh
     * @param refreshEnable true or false
     * */
    public void toEnableRefresh(boolean refreshEnable) {
        if (null != refreshLayout) {
            refreshLayout.setEnabled(refreshEnable);
        } else {
            onSupplyRefreshLayout().setEnabled(refreshEnable);
        }
    }

    /**
     * switch enable load more
     * @param loadMoreEnable true or false
     * */
    public void toEnableLoadMore(boolean loadMoreEnable) {
        if (null != adapter) {
            if (!loadMoreEnable) {
                //由于 adapter.setList(xxx) 方法会重置加载更多状态，
                //如果设置允许刷新不允许加载更多，那么为了防止刷新后新设置数据导致状态重置
                //将回调主动设置为null,就不会重置状态了
                adapter.getLoadMoreModule().setOnLoadMoreListener(null);
            } else {
                adapter.getLoadMoreModule().setOnLoadMoreListener(this::onBackLoadMore);
            }
            adapter.getLoadMoreModule().setEnableLoadMore(loadMoreEnable);
        }
    }

    /**
     * dismiss RefreshLayout when operator end
     * */
    public void toDismissRefresh() {
        if (null != refreshLayout) {
            refreshLayout.setRefreshing(false);
        }

        if (null != adapter) {
            //刷新结束后，重置加载更多为默认状态，因为刷新过程为了防止可以加载更多设置为 false 了
            //放心 toEnableLoadMore 会再次判断
            adapter.getLoadMoreModule().setEnableLoadMore(true);
        }
    }

    /**
     * dismiss LoadMoreLayout when operator end
     * @param isSuccess true or false
     * */
    public void toDismissLoadMore(boolean isSuccess) {
        if (null != adapter) {
            if (isSuccess) {
                adapter.getLoadMoreModule().loadMoreEnd(true);
            } else {
                adapter.getLoadMoreModule().loadMoreFail();
            }
        }
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        initAdapter();
        super.onCreate(savedInstanceState);

        initRefreshLayout();
        initRecyclerView();
    }

    private void initRefreshLayout() {
        refreshLayout = onSupplyRefreshLayout();

        if (null != refreshLayout) {
            refreshLayout.setColorSchemeColors(Color.rgb(47, 223, 189));
            refreshLayout.setOnRefreshListener(() -> {
                //这里的作用是防止下拉刷新的时候还可以上拉加载
                if (null != adapter) {
                    adapter.getLoadMoreModule().setEnableLoadMore(false);
                }

                onBackRefreshing();
            });
        }
    }

    private void initAdapter() {
        adapter = onSupplyAdapter();

        if (null != adapter) {
            adapter.toBindDataChange(this);
            adapter.toBindItem(onSupplyItemBinder());

            adapter.setItemClickListener(this::onBackItemClicked);
            adapter.setItemLongClickListener(CommonListActivity.this::onBackItemLongClicked);
            adapter.setItemChildClickListener((this::onBackItemChildClicked));
            adapter.setItemChildLongClickListener(CommonListActivity.this::onBackItemChildLongClicked);

            adapter.setAnimationWithDefault(BaseQuickAdapter.AnimationType.AlphaIn);
            adapter.getLoadMoreModule().setOnLoadMoreListener(this::onBackLoadMore);
        } else {
            throw new SupplyIsNullException("adapter");
        }
    }

    private void initRecyclerView() {
        recyclerView = onSupplyRecyclerView();
        if (null != recyclerView) {
            recyclerView.setLayoutManager(onSupplyLayoutManager());
            recyclerView.setAdapter(adapter);
            if (null != onSupplyItemDecoration()) {
                recyclerView.addItemDecoration(onSupplyItemDecoration());
            }
        } else {
            throw new SupplyIsNullException("recyclerView");
        }
    }

    public A currentAdapter() {
        return adapter;
    }

    /**
     * logic for loading more on background
     * */
    protected void onBackLoadMore() {
        //child do onBackground
    }

    /**
     * logic for refreshing on background
     * */
    protected void onBackRefreshing() {
        //then
        //child do onBackground
        //...
    }

    @Override
    public void update(Observable o, Object arg) {
        if (arg instanceof List) {
            onBackDataChanged((List<T>) arg);
        }
    }

    /**
     * 监听数据变化（点击item），如果您使用单选或者多选功能会触发改效果
     * */
    protected void onBackDataChanged(List<T> list) {

    }

    /**
     * 如果不想在 binder 里处理点击回调可以在该回调方法中处理
     * */
    protected void onBackItemClicked(@NonNull View view, int position, @Nullable T t) {

    }

    /**
     * 如果不想在 binder 里处理长按回调可以在该回调方法中处理
     * */
    protected boolean onBackItemLongClicked(@NonNull View view, int position, @Nullable T t) {
        return false;
    }

    /**
     * 如果不想在 binder 里处理item内部控件点击回调可以在该回调方法中处理
     * */
    protected void onBackItemChildClicked(@NonNull View view, int position, @Nullable T t) {

    }

    /**
     * 如果不想在 binder 里处理item内部控件长按回调可以在该回调方法中处理
     * */
    protected boolean onBackItemChildLongClicked(@NonNull View view, int position, @Nullable T t) {
        return false;
    }
}
